package com.hnkywl.sts.service.organ;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.hnkywl.sts.dao.organ.EjzhDao;
import com.hnkywl.sts.dao.organ.KhhDao;
import com.hnkywl.sts.dao.organ.NbgsDao;
import com.hnkywl.sts.dao.sfgl.SkshDao;
import com.hnkywl.sts.dao.xsgl.DfkxsdDao;
import com.hnkywl.sts.dao.xsgl.XsdDao;
import com.hnkywl.sts.entity.base.Sjzdz;
import com.hnkywl.sts.entity.organ.Ejzh;
import com.hnkywl.sts.entity.organ.Gsjg;
import com.hnkywl.sts.entity.organ.Nbgs;
import com.hnkywl.sts.entity.organ.Qyjg;
import com.hnkywl.sts.entity.sfgl.Sfk;
import com.hnkywl.sts.entity.xsgl.Dfkxsd;
import com.hnkywl.sts.service.base.BmService;
import com.hnkywl.sts.service.base.DxpzService;
import com.hnkywl.sts.service.sys.YgService;
import com.hnkywl.sts.util.BaseUtils;
import com.hnkywl.sts.util.ReflectionUtils;
import net.ruixin.orm.hibernate.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: Administrator
 * Date: 13-3-25
 * Time: 下午3:38
 * To change this template use File | Settings | File Templates.
 */
@Service
public class EjzhService {
    private EjzhDao ejzhDao;
    private GsjgService gsjgService;
    private DfkxsdDao dfkxsdDao;
    private BmService bmService;
    private SkshDao skshDao;
    private KhhDao khhDao;
    private DxpzService dxpzService;
    private XsdDao xsdDao;
    private NbgsDao nbgsDao;

    @Transactional
    public String findEjzhList(Long nbgsId, String qc, String jc, int pageNo, int pageSize) {
        Page<Ejzh> khhPage = this.ejzhDao.findEjzhList(nbgsId, qc, jc, pageNo, pageSize);
        String khhJson = BaseUtils.fetchCollectionToJson(khhPage.getResult(), "id", "jc", "qc", "nbgs.id", "nbgs.qc", "khh.jc", "kyye", "kh.qc", "ye", "zh", "bzj", "sxe");
        return "{\"total\":" + khhPage.getTotalCount() + ",\"rows\":[" + khhJson + "]}";
    }

    @Transactional
    public Ejzh findEjzhById(Long id) {
        return this.ejzhDao.get(id);
    }

    public List<Ejzh> findEjzhByKhhId(Long khhId) {
        return this.ejzhDao.findEjzhByKhhId(khhId);
    }

    /**
     * 保存开户行信息
     *
     * @param
     * @return
     */
    @Transactional
    public void saveEjzh(Ejzh ejzh) {
        if (ejzh.getKh() == null || ejzh.getKh().getId() == null) {
            throw new RuntimeException("二级账户客户必填");
        }
        if (checkKhUnique(ejzh.getNbgs().getId(), null, ejzh.getKh().getId())) {
            Nbgs nbgs = nbgsDao.get(ejzh.getNbgs().getId());
            throw new RuntimeException("该客户在" + nbgs.getJc() + "下已经建立过二级账户，不可重复建立");
        }
        ejzh.setCreateUser(YgService.getCurrentYg());
        ejzh.setCreateOrgan(YgService.getCurrentYg().getZggs());
        ejzh.setCreateDepartment(YgService.getCurrentYg().getZgjg());
        ejzh.setDateCreated(new Date());
        ejzh.setLastUpdated(ejzh.getDateCreated());
        ejzh.setKhh(khhDao.get(ejzh.getKhh().getId()));
        this.ejzhDao.save(ejzh);
    }

    /**
     * 更新工程信息
     *
     * @param
     * @return
     */
    @Transactional
    public void updateEjzh(Ejzh ejzh) throws RuntimeException {
        if (ejzh.getKh() == null || ejzh.getKh().getId() == null) {
            throw new RuntimeException("二级账户客户必填");
        }
        if (checkKhUnique(ejzh.getId(), ejzh.getId(), ejzh.getKh().getId())) {
            throw new RuntimeException("客户已经建立过二级账户，不可重复建立");
        }
        Ejzh clone = this.ejzhDao.get(ejzh.getId());
        clone = (Ejzh) ReflectionUtils.getInstance(clone, ejzh);
        clone.setLastUpdated(new Date());
        this.ejzhDao.save(clone);
    }

    /**
     * 删除开户行信息
     *
     * @param id 开户行ID
     * @return
     */
    @Transactional
    public void deleteEjzh(Long id) {
        Ejzh ejzh = ejzhDao.get(id);
        ejzh.setLastUpdated(new Date());
        ejzh.setDeleted(1);
        this.ejzhDao.save(ejzh);
    }

    /**
     * 通过客户Esb Code查询可用余额
     *
     * @param memberCode
     * @return
     */
    @Transactional
    public String findKyyeByKhEsbCode(String memberCode, String parentSalerCode) {
        StringBuilder sb = new StringBuilder();
        Gsjg kh = gsjgService.findKhByEsbcode(memberCode);
        Gsjg parentSaler = gsjgService.findKhByEsbcode(parentSalerCode);
        Ejzh e = this.ejzhDao.findKyyeByKhId(kh.getId(), parentSaler.getId());
        Double ye = e.getKyye() == null ? 0 : e.getKyye();
        BigDecimal yeDecimal = new BigDecimal(ye);
        java.text.DecimalFormat df = new java.text.DecimalFormat("#,###.00");
        sb.append("{\"code\":\"0\",\"flag\":\"0\",\"message\":\"成功\",\"status\":\"0\",\"balance\":\"" + df.format(yeDecimal) + "\"}");
        return sb.toString();
    }

    /**
     * 锁定二级账户余额
     *
     * @param
     * @return
     */
    @Transactional
    public String lockAccountBalance(String param, Long serialNumber) {
        java.text.DecimalFormat df = new java.text.DecimalFormat("#,###.00");
        Gson gson = new Gson();
        StringBuilder sb = new StringBuilder();
        Map<String, Object> resultList = gson.fromJson(param, new TypeToken<Map<String, Object>>() {
        }.getType());
        Long htId = Long.parseLong(resultList.get("order_id").toString());
        String htbm = resultList.get("order_sn").toString();
        Double amount = Double.parseDouble(resultList.get("amount").toString());
        String memberCode = resultList.get("memberCode").toString();
        String salerCode = resultList.get("salerCode").toString();
        String parentSalerCode = resultList.get("parentSalerCode").toString();
        //查询代付款销售单
        Dfkxsd d = dfkxsdDao.findDfkXsdByHt(htId, htbm, amount);

        //买家有两种情况：1.memberCode是物流园专场电子超市客户，2.memberCode是物流园赎货专场代理客户
        Gsjg buyer = gsjgService.findKhByEsbcode(memberCode);
        //卖家有两种情况：1.salerCode是物流园专场电子超市代理客户，2.salerCode是物流园赎货专场的物流园
        Gsjg saler = gsjgService.findKhByEsbcode(salerCode);
        Gsjg parentSaler = gsjgService.findKhByEsbcode(parentSalerCode);

        //买家二级账户
        Ejzh buyerAccount = ejzhDao.findKyyeByKhId(buyer.getId(), parentSaler.getId());
        //卖家二级客户
        Ejzh salerAccount = ejzhDao.findKyyeByKhId(saler.getId(), parentSaler.getId());
        //如果代付款销售单不为空，则该销售单已经锁定
        if (d != null) {
            sb.append("{\"code\":\"8\",\"flag\":\"1\",\"message\":\"客户资金锁定失败！原因：合同 " + htbm +
                    " 已存在锁款记录请先解锁\",\"balance\":\"" + df.format(new BigDecimal(buyerAccount.getKyye())) + "\",\"lockedAmount\":\"" + df.format(new BigDecimal(amount)) + "\"}");
            return sb.toString();
        }
        //如果买家账户余额小于订单金额
        if (buyerAccount.getKyye() < amount) {
            sb.append("{\"code\":\"1\",\"flag\":\"1\",\"message\":\"买方可用余额不足，不可锁定！\",\"balance\":\""
                    + df.format(new BigDecimal(buyerAccount.getKyye())) + "\",\"lockedAmount\":\"" + df.format(new BigDecimal(Double.parseDouble(resultList.get("amount").toString()))) + "\"}");
            return sb.toString();
        }
        //新增代付款销售单保存锁定数据
        Dfkxsd dfkxsd = new Dfkxsd();
        dfkxsd.setAmount(amount);
        dfkxsd.setMemberCode(memberCode);
        dfkxsd.setOrderId(htId);
        dfkxsd.setOrderSn(htbm);
        dfkxsd.setSalerCode(salerCode);
        dfkxsd.setLockSerialNumber(serialNumber);
        dfkxsd.setDateCreated(new Date());
        dfkxsd.setLastUpdated(dfkxsd.getDateCreated());
        //新增收款
        Sfk sfk = new Sfk();
        sfk.setSbgs(saler);
        sfk.setGldw(buyer);
        //外部付款
        sfk.setWlzlx(1);
        sfk.setDateCreated(new Date());
        sfk.setSfje(amount);
        sfk.setLastUpdated(sfk.getDateCreated());
        sfk.setCreateUser(null);
        sfk.setCreateOrgan(buyerAccount.getKhh().getNbgs());
        sfk.setCreateDepartment(null);
        sfk.setBm(this.bmService.getSfdbm("SK"));
        sfk.setSfklx(3);//销售收款
        sfk.setKxlx(4);//应收款
        sfk.setNbkhh(salerAccount.getKhh());
        Sjzdz pjlx = new Sjzdz();
        pjlx.setId(144L);
        sfk.setPjlx(pjlx);//票据类型  其他
        Sjzdz kxyt = new Sjzdz();
        kxyt.setId(132L);
        sfk.setKxyt(kxyt);
        sfk.setShrq(new Date());
        sfk.setZt("ysh");
        sfk.setSfkrq(new Date());

        //买方二级客户可用余额
        Double buyerBalance = buyerAccount.getKyye() - amount;
        //买方二级客户余额
        Double buyerYeBalance = buyerAccount.getYe() - amount;
        //卖方二级客户可用余额
        Double salerBalance = salerAccount.getKyye() + amount;
        //卖方二级客户可用余额
        Double salerYeBalance = salerAccount.getYe() + amount;
        //修改电子超市客户二级账户可用余额
        buyerAccount.setKyye(buyerBalance);
        buyerAccount.setYe(buyerYeBalance);
        buyerAccount.setLastUpdated(new Date());
        //锁定二级账户
        ejzhDao.save(buyerAccount);
        //修改代理客户二级账户可用余额
        salerAccount.setKyye(salerBalance);
        salerAccount.setYe(salerYeBalance);
        salerAccount.setLastUpdated(new Date());
        //锁定二级账户
        ejzhDao.save(salerAccount);
        dfkxsd.setSdfk(sfk);
        dfkxsd.setMessage("锁定账户");
        dfkxsdDao.save(dfkxsd);
        //贷方二级账户，买方二级账户
        sfk.setDfejzh(buyerAccount);
        //借方二级账户，卖方二级账户
        sfk.setJfejzh(salerAccount);
        this.skshDao.save(sfk);
        sb.append("{\"code\":\"0\",\"flag\":\"0\",\"message\":\"锁定账户成功！\",\"balance\":\"" + df.format(new BigDecimal(buyerBalance)) +
                "\",\"lockedAmount\":\"" + df.format(new BigDecimal(resultList.get("amount").toString())) + "\"}");
        dxpzService.sendSMS("XJJYTX", salerAccount.getKh().getLxsj(), salerAccount.getKh().getJc(), new SimpleDateFormat("yyyy年MM月dd日").format(new Date()),
                "支付", String.format("%.2f", amount), String.format("%.2f", salerAccount.getYe()));
        dxpzService.sendSMS("XJJYTX", buyerAccount.getKh().getLxsj(), buyerAccount.getKh().getJc(), new SimpleDateFormat("yyyy年MM月dd日").format(new Date()),
                "收到", String.format("%.2f", amount), String.format("%.2f", buyerAccount.getYe()));
        return sb.toString();
    }


    /**
     * 解锁二级账户余额
     *
     * @param
     * @return
     */
    @Transactional
    public String unlockAccountBalance(String param, Long serialNumber) {
        java.text.DecimalFormat df = new java.text.DecimalFormat("#,###.00");
        Gson gson = new Gson();
        StringBuilder sb = new StringBuilder();
        Map<String, Object> resultList = gson.fromJson(param, new TypeToken<Map<String, Object>>() {
        }.getType());
        Long htId = Long.parseLong(resultList.get("order_id").toString());
        String htbm = resultList.get("order_sn").toString();
        Double amount = Double.parseDouble(resultList.get("amount").toString());
        String memberCode = resultList.get("memberCode").toString();
        String salerCode = resultList.get("salerCode").toString();
        String parentSalerCode = resultList.get("parentSalerCode").toString();

        //买家有两种情况：1.memberCode是物流园专场电子超市客户，2.memberCode是物流园赎货专场代理客户
        Gsjg buyer = gsjgService.findKhByEsbcode(memberCode);
        //卖家有两种情况：1.salerCode是物流园专场电子超市代理客户，2.salerCode是物流园赎货专场的物流园
        Gsjg saler = gsjgService.findKhByEsbcode(salerCode);
        Gsjg parentSaler = gsjgService.findKhByEsbcode(parentSalerCode);
        //买家二级账户
        Ejzh buyerAccount = this.ejzhDao.findKyyeByKhId(buyer.getId(), parentSaler.getId());
        //卖家二级客户
        Ejzh salerAccount = this.ejzhDao.findKyyeByKhId(saler.getId(), parentSaler.getId());

        //验证代付款销售单的正确性
        Dfkxsd dfkxsd = dfkxsdDao.findDfkXsdByHt(htId, htbm, amount);
        //卖方可用余额小于销售单金额
        if (salerAccount.getKyye() < amount) {
            sb.append("{\"code\":\"1\",\"flag\":\"1\",\"message\":\"卖方可用余额不足，不可解锁！\"}");
            return sb.toString();
        }
        if (dfkxsd == null) {
            sb.append("{\"code\":\"1\",\"flag\":\"1\",\"message\":\"二级账户没有锁定，不可解锁！\"}");
        } else {
            //买方二级客户可用余额
            Double buyerBalance = buyerAccount.getKyye() + amount;
            Double buyerYeBalance = buyerAccount.getYe() + amount;
            //卖方二级客户可用余额
            Double salerBalance = salerAccount.getKyye() - amount;
            Double salerYeBalance = salerAccount.getYe() - amount;
            //买方二级账户可用余额增加
            buyerAccount.setKyye(buyerBalance);
            buyerAccount.setYe(buyerYeBalance);
            //卖方二级账户可用余额减少
            salerAccount.setKyye(salerBalance);
            salerAccount.setYe(salerYeBalance);

            this.ejzhDao.save(buyerAccount);
            this.ejzhDao.save(salerAccount);
            //删除待处理销售单的付款记录
            Sfk sfk = dfkxsd.getSdfk();
            sfk.setLastUpdated(new Date());
            sfk.setZt("yth");
            this.skshDao.save(sfk);
            //删除待处理销售单数据
            dfkxsd.setDeleted(1);
            dfkxsd.setUnlockSerialNumber(serialNumber);
            dfkxsd.setBz("解锁账户");
            dfkxsd.setLastUpdated(new Date());
            dfkxsdDao.save(dfkxsd);
            sb.append("{\"code\":\"0\",\"flag\":\"0\",\"message\":\"解锁账户成功\",\"balance\":\"" + df.format(new BigDecimal(buyerBalance)) + "\",\"lockedAmount\":\"" + df.format(new BigDecimal(Double.parseDouble(resultList.get("amount").toString()))) + "\"}");
        }
        return sb.toString();
    }


    /**
     * ajax远程验证
     *
     * @param value 验证值
     * @param field 验证字段
     * @return
     */
    public boolean ajaxValidate(Long id, String value, String field) {
        return ejzhDao.checkUnique(id, value, field);
    }

    @Transactional
    public String findEjzhByKhId(Long khId, Long gsId) {
        List<Ejzh> e = ejzhDao.findEjzhListByKhId(khId, gsId);
        String qyjgJson = BaseUtils.fetchCollectionToJson(e, "id", "jc", "ye");
        return "[" + qyjgJson + "]";
    }

    @Transactional
    public String findEjzhByKhAndNbgsId(Long ejzhId, Long nbgsId) {
        Gsjg kh = new Gsjg();
        kh.setId(ejzhId);
        List<Ejzh> khhs = ejzhDao.findEjzhByKhAndNbgsId(ejzhId, nbgsId);
        String qyjgJson = BaseUtils.fetchCollectionToJson(khhs, "id", "jc", "ye");
        return "[" + qyjgJson + "]";
    }

    public int checkKyye(Long khId, Long xsdId) {
        int result = 0;
        List<Map> list = ejzhDao.findKyyeByKh(khId);
        List<Map> zes = xsdDao.findSumZe(xsdId);
        Double kyye = Double.parseDouble(list.get(0).get("KYYE").toString());
        if (kyye > 0) {
            Double ze = Double.parseDouble(zes.get(0).get("ZE").toString());
            if (kyye < ze) {
                result = 1;
            } else {
                result = 2;
            }
        } else {
            result = 3;
        }
        return result;
    }


    public boolean checkKhUnique(Long gsId, Long erzhId, Long khId) {
        return ejzhDao.checkKhUnique(gsId, erzhId, khId);
    }


    @Autowired
    public void setEjzhDao(EjzhDao ejzhDao) {
        this.ejzhDao = ejzhDao;
    }


    @Autowired
    public void setGsjgService(GsjgService gsjgService) {
        this.gsjgService = gsjgService;
    }

    @Autowired
    public void setDfkxsdDao(DfkxsdDao dfkxsdDao) {
        this.dfkxsdDao = dfkxsdDao;
    }

    @Autowired
    public void setBmService(BmService bmService) {
        this.bmService = bmService;
    }

    @Autowired
    public void setSkshDao(SkshDao skshDao) {
        this.skshDao = skshDao;
    }

    @Autowired
    public void setKhhDao(KhhDao khhDao) {
        this.khhDao = khhDao;
    }

    @Autowired
    public void setDxpzService(DxpzService dxpzService) {
        this.dxpzService = dxpzService;
    }

    @Autowired
    public void setXsdDao(XsdDao xsdDao) {
        this.xsdDao = xsdDao;
    }

    @Autowired
    public void setNbgsDao(NbgsDao nbgsDao) {
        this.nbgsDao = nbgsDao;
    }
}
